package com.jn.erp.web.api.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.jn.erp.common.core.page.TableDataInfo;

import com.jn.erp.common.core.result.AjaxResult;
import com.jn.erp.common.utils.StringUtils;
import com.jn.erp.security.controller.BaseWebAuthController;
import com.jn.erp.security.entity.LoginUser;
import com.jn.erp.security.entity.SysRole;
import com.jn.erp.security.entity.SysUser;
import com.jn.erp.security.entity.SysUserRole;
import com.jn.erp.security.service.TokenService;
import com.jn.erp.security.sysservice.SysRoleService;
import com.jn.erp.security.sysservice.SysUserRoleService;
import com.jn.erp.security.sysservice.SysUserService;
import com.jn.erp.web.api.sys.entity.SysRolePermission;
import com.jn.erp.web.api.sys.service.SysRolePermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <pre>
 *
 * </pre>
 *
 * @author sunjiyong
 * @since 2024/8/28 19:51
 */
@RestController
@RequestMapping("/system/role")
public class SysRoleController extends BaseWebAuthController {


    @Autowired
    private TokenService tokenService;
    @Autowired
    private SysRoleService sysRoleService;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private SysUserRoleService sysUserRoleService;
    @Autowired
    private SysRolePermissionService sysRolePermissionService;
    @Autowired
    private com.jn.erp.security.service.SysPermissionService securityPermissionService;

    /**
     * 获取机构列表
     */
//    @PreAuthorize("@ss.hasPermi('system:dept:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysRole sysRole){
        startPage();
        List<SysRole> roles = sysRoleService.selectRoleList(sysRole);
        return getDataTable(roles);
    }


    /**
     * 根据角色编号获取详细信息
     */
//    @PreAuthorize("@ss.hasPermi('system:role:query')")
    @GetMapping(value = "/{roleId}")
    public AjaxResult getInfo(@PathVariable Long roleId) {
//        roleService.checkRoleDataScope(roleId);
        return success(sysRoleService.getById(roleId));
    }


    /**
     * 新增角色
     */
//    @PreAuthorize("@ss.hasPermi('system:role:add')")
//    @Log(title = "角色管理", businessType = BusinessType.INSERT)
    @PostMapping
    @Transactional
    public AjaxResult add(@Validated @RequestBody SysRole role) {
        String s = loginDeptAuth();
        if (!sysRoleService.checkRoleNameUnique(role)) {
            return error("新增角色'" + role.getRoleName() + "'失败，角色名称已存在");
        } else if (!sysRoleService.checkRoleKeyUnique(role)) {
            return error("新增角色'" + role.getRoleName() + "'失败，角色权限已存在");
        }
        role.setCreateBy(getUsername());
        role.setCreateTime(new Date());
        role.setOrgId(Long.valueOf(s));
        sysRoleService.save(role);
        sysRolePermissionService.insertRoleMenu(role);
        return toAjax(true);

    }


    /**
     * 删除角色
     */
//    @PreAuthorize("@ss.hasPermi('system:role:remove')")
//    @Log(title = "角色管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{roleIds}")
    @Transactional
    public AjaxResult remove(@PathVariable Long[] roleIds) {
        sysRoleService.deleteRoleByIds(roleIds);
        // 删除角色与菜单关联
        QueryWrapper<SysRolePermission> qw=new QueryWrapper<>();
        qw.in("role_id",roleIds);
        sysRolePermissionService.remove(qw);
        QueryWrapper<SysUserRole> qwr=new QueryWrapper<>();
        qwr.in("role_id",roleIds);
        sysUserRoleService.remove(qwr);
        return toAjax(true);
    }


    /**
     * 状态修改
     */
//    @PreAuthorize("@ss.hasPermi('system:role:edit')")
//    @Log(title = "角色管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody SysRole role) {
        sysRoleService.checkRoleAllowed(role);
//        sysRoleService.checkRoleDataScope(role.getRoleId());
        role.setUpdateBy(getUsername());
        role.setUpdateTime(new Date());
        return toAjax(sysRoleService.updateById(role));
    }

    /**
     * 修改保存角色
     */
//    @PreAuthorize("@ss.hasPermi('system:role:edit')")
//    @Log(title = "角色管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysRole role) {
        sysRoleService.checkRoleAllowed(role);
//        sysRoleService.checkRoleDataScope(role.getRoleId());
        if (!sysRoleService.checkRoleNameUnique(role)) {
            return error("修改角色'" + role.getRoleName() + "'失败，角色名称已存在");
        } else if (!sysRoleService.checkRoleKeyUnique(role)) {
            return error("修改角色'" + role.getRoleName() + "'失败，角色权限已存在");
        }
        role.setUpdateBy(getUsername());

        if (sysRoleService.updateById(role)) {
            QueryWrapper<SysRolePermission> qwr=new QueryWrapper();
            qwr.eq("role_id",role.getRoleId() );
            sysRolePermissionService.remove(qwr);
            sysRolePermissionService.insertRoleMenu(role);
            // 更新缓存用户权限
            LoginUser loginUser = getLoginUser();
            if (StringUtils.isNotNull(loginUser.getUser()) && !(loginUser.getUser().getId()==1l)) {
                loginUser.setPermissions(securityPermissionService.getMenuPermission(loginUser.getUser()));
                QueryWrapper<SysUser> qw=new QueryWrapper<>();
                qw.eq("name",loginUser.getUser().getName());
                loginUser.setUser(sysUserService.getOne(qw));
                tokenService.setLoginUser(loginUser);
            }
            return success();
        }
        return error("修改角色'" + role.getRoleName() + "'失败，请联系管理员");
    }


    /**
     * 查询已分配用户角色列表
     */
//    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping("/authUser/allocatedList")
    public TableDataInfo allocatedList(SysUser user) {
        startPage();
        List<SysUser> list = sysUserService.selectAllocatedList(user);
        return getDataTable(list);
    }


    /**
     * 查询未分配用户角色列表
     */
//    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping("/authUser/unallocatedList")
    public TableDataInfo unallocatedList(SysUser user) {
        startPage();
        List<SysUser> list = sysUserService.selectUnallocatedList(user);
        return getDataTable(list);
    }


    /**
     * 取消授权用户
     */
//    @PreAuthorize("@ss.hasPermi('system:role:edit')")
//    @Log(title = "角色管理", businessType = BusinessType.GRANT)
    @PutMapping("/authUser/cancel")
    public AjaxResult cancelAuthUser(@RequestBody SysUserRole userRole) {
        QueryWrapper<SysUserRole> qw=new QueryWrapper<>();
        qw.eq("user_id",userRole.getUserId());
        qw.eq("role_id",userRole.getRoleId());
        sysUserRoleService.remove(qw);
        return toAjax(true);
    }

    /**
     * 批量取消授权用户
     */
//    @PreAuthorize("@ss.hasPermi('system:role:edit')")
//    @Log(title = "角色管理", businessType = BusinessType.GRANT)
    @PutMapping("/authUser/cancelAll")
    public AjaxResult cancelAuthUserAll(Long roleId, Long[] userIds) {
        QueryWrapper<SysUserRole> qw=new QueryWrapper<>();
        qw.in("user_id",userIds);
        qw.eq("role_id",roleId);
        sysUserRoleService.remove(qw);
        return toAjax(true);
    }

    /**
     * 批量选择用户授权
     */
//    @PreAuthorize("@ss.hasPermi('system:role:edit')")
//    @Log(title = "角色管理", businessType = BusinessType.GRANT)
    @PutMapping("/authUser/selectAll")
    public AjaxResult selectAuthUserAll(Long roleId, Long[] userIds) {
        // 新增用户与角色管理
        List<SysUserRole> list = new ArrayList<SysUserRole>();
        for (Long userId : userIds) {
            SysUserRole ur = new SysUserRole();
            ur.setUserId(userId);
            ur.setRoleId(roleId);
            list.add(ur);
        }
        sysUserRoleService.saveBatch(list);
//        roleService.checkRoleDataScope(roleId);
        return toAjax(true);
    }

    //用于web配置移动端角色列表
    @PostMapping("/selectRoleOrg")
    public AjaxResult selectRoleOrg() {
        String s = loginDeptAuth();
        SysRole sysRole=new SysRole();
        sysRole.setOrgId(Long.valueOf(s));
        List<SysRole> sysRoles = sysRoleService.selectRoleOrg(sysRole);
        Map<String, List<SysRole>> collect = sysRoles.stream().collect(Collectors.groupingBy(SysRole::getOrgName));
        return success(collect);
    }

}
